package com.kancy.vip.pattern.singleton.lazy;

public class LazyDoubleCheckSingleton {
    /**
     * 加上volatile，防止对象初始化过程中的指令重排序
     */
    private volatile static LazyDoubleCheckSingleton lazy = null;

    private LazyDoubleCheckSingleton(){
        // 无法很好防止反射破坏
    }

    /**
     * 防止序列化破坏
     * readResolveMethod = getInheritableMethod(cl, "readResolve", null, Object.class);
     */
    private Object readResolve(){
        return lazy;
    }

    public static LazyDoubleCheckSingleton getInstance(){
        if(lazy == null){
            synchronized(LazyDoubleCheckSingleton.class){
                // 当多个线程都进入第一个判断时，不进行二次判断，会出现线程安全问题，lazy会被多次初始化覆盖
                if(lazy == null){
                    lazy = new LazyDoubleCheckSingleton();
                    // 2,3步骤会进行指令的重排序优化，所以double check也不一定完全线程安全，可用volatile来禁止指令重排序实现终极线程安全
                    // 1. 分配内存空间
                    // 2. 对象初始化
                    // 3. 将内存空间地址与引用建立连接
                    // 4. 对象可以被使用
                }
            }
        }
        return lazy;
    }
}
